#include "main.h"

/*! 测试结构体 */
#if 0
struct MemoryStruct {
  char *memory;
  size_t size;
};
#endif

int main()
{

/*! 百度云测试 */
/* 5.2 向服务器添加人脸  */
#if 0
   using namespace std;
   using namespace Json;
   using namespace BaiDuYun;
   const string ak = API_KEY; 
   const string sk = SECRET_KEY;

   // 建立 face句柄，并向服务器请求密钥
   Face face(ak, sk);
   string photoBuf;
#if 1
   ifstream jpegFile("misc/new.jpeg", ios_base::in|ios_base::binary);
   if(jpegFile.is_open()){
     basic_istream<char>::pos_type photoSize = 0;

     /*！ 读取文件的大小,并为string分配合适的内存空间 */
     jpegFile.seekg(0, ios_base::end);
     photoSize = jpegFile.tellg();
     photoBuf.resize(static_cast<size_t>(photoSize)+1, 0);

     /*! 读取图像数据 */
     /* Hint:此操作十分危险，需要对底层有一定程度的了解 */
     jpegFile.seekg(0, ios_base::beg);
     jpegFile.read(const_cast<char *>(photoBuf.data()) , photoSize);

     /*! 关闭文件 */
     jpegFile.close();
   }else{
     cout<<"图片文件打开失败!"<<endl;
   }
#endif   

   face["image_type"] = "BASE64";
   face["liveness_control"]  = "NONE";
   if(face.FaceUpdate(photoBuf))
     cout<<"SUCESS"<<endl;
   else
     cout<<face.curErrorMsg<<endl;
#endif

/*! 服务器测试 */
/* 6.1 尝试建立服务器 */
#if  1
   DockSever::DockSeverInit();
   return 0;
#endif


}

/*********************************** 测试代码(START) ***********************************/
/*! Base64编解码测试 */
#if 0
    string buf = "Error:cannot call member function without object class Base";
    std::string base64_encode_result, base64_decode_result;
    cout<<"原始字符串："<<buf<<endl;
    base64_encode_result = Base64::Encode(buf.c_str(), buf.length());
    cout<<"Base64编码："<<base64_encode_result<<endl;
    base64_decode_result = Base64::Decode(base64_encode_result.c_str(),
                           base64_encode_result.length());
    cout<<"Base64解码："<<base64_decode_result<<endl;
#endif

/*! JSON解析(文件) */
#if 0
    using namespace std;
    /*! 从文件中读取json字符串 */
    ifstream ifile_json("../misc/config_doc");
    string  string_json;
    string_json.reserve(1024);
    cout<<"sting缓冲区大小:"<< string_json.capacity() <<endl<<endl;
    if(ifile_json.good()){
#define  BUF_SIZE  256
      char* buf = new char[BUF_SIZE];
      while(1){
          ifile_json.clear();
          ifile_json.getline(buf, BUF_SIZE);
          string_json = string_json + static_cast<string>(buf);
          ifile_json.get();                                     //读取'\n'
          if(ifile_json.rdstate()  && ios_base::eofbit) break;
      }  
      delete[] buf;
      cout<<"从文件中读取的json字符串为:"<<endl<<string_json<<endl;
#undef   BUF_SIZE 
    }else{
        cout<<"打开config_doc文件失败."<<endl;
        exit(-1);
    }

    /*! 解析JSON字符串 */
    Json::Value root;   
    JSONCPP_STRING errs;
    Json::CharReaderBuilder readerBuilder;
    Json::CharReader* jsonReader = readerBuilder.newCharReader();
    bool parsingSuccessful = jsonReader->parse(string_json.c_str(), string_json.c_str()
                                +string_json.length(), &root, &errs);
    if ( !parsingSuccessful ){
        cout  << "JSON解析失败"<<std::endl;
        return -1;
    }else{
        cout  << "JSON解析成功"<<std::endl;
    }
    return 0;
#endif

/*! Jsoncpp测试 */
/* 1.1 - 查看默认Json解析的配置 */
#if 0
using namespace std;
    Json::Features json_features;

    cout<<"原始Jsoncpp配置:"<<endl;
    cout<<boolalpha<<"是否允许C/C++ style风格注释:"  << json_features.allowComments_                <<endl;
    cout<<boolalpha<<"是否允许数组为对象值:"          << json_features.strictRoot_                   <<endl;
    cout<<boolalpha<<"是否允许空格出现在json中:"      << json_features.allowDroppedNullPlaceholders_ <<endl;
    cout<<boolalpha<<"是否允许数字对象键:"            << json_features.allowNumericKeys_             <<endl;
    cout<<endl;
    
    json_features.all();
    cout<<"使用all()进行配置后:"<<endl;
    cout<<boolalpha<<"是否允许C/C++ style风格注释:"  << json_features.allowComments_                <<endl;
    cout<<boolalpha<<"是否允许数组为对象值:"          << json_features.strictRoot_                   <<endl;
    cout<<boolalpha<<"是否允许空格出现在json中:"      << json_features.allowDroppedNullPlaceholders_ <<endl;
    cout<<boolalpha<<"是否允许数字对象键:"            << json_features.allowNumericKeys_             <<endl;
    cout<<endl;

    json_features.strictMode();
    cout<<"使用strictMode()进行配置后:"<<endl;
    cout<<boolalpha<<"是否允许C/C++ style风格注释:"  << json_features.allowComments_                <<endl;
    cout<<boolalpha<<"是否允许数组为对象值:"          << json_features.strictRoot_                   <<endl;
    cout<<boolalpha<<"是否允许空格出现在json中:"      << json_features.allowDroppedNullPlaceholders_ <<endl;
    cout<<boolalpha<<"是否允许数字对象键:"            << json_features.allowNumericKeys_             <<endl;
    cout<<endl;

    return 0;
#endif

/*! Jsoncpp测试 */
/* 2.1 Jsoncpp:value.h构造函数测试 */
/* 测试构造函数以及type成员函数 */
#if 0
   using namespace std;
   using namespace Json;
   string& PrintType(const ValueType& vaule_type);

   Value value1;
   Value value2(arrayValue);
   Value value3(objectValue);
   Value value4(1);
   Value value5(1.0);
   Value value6("Hello World");
   Value value7(true);
   
   cout<<"构造函数配置:"<<endl;
   cout<<"(1) Value(ValueType type = nullValue);"<<endl;
   cout<<"(2) Value(ValueType type = nullValue);"<<endl;
   cout<<"(3) Value(ValueType type = nullValue);"<<endl;
   cout<<"(4) Value(UInt value);"<<endl;
   cout<<"(5) Value(double value);"<<endl;
   cout<<"(6) Value(const char* value);"<<endl;
   cout<<"(7) Value(bool value);"<<endl<<endl;

   cout<<"使用各种构造函数后Value对象类型："<<endl;
   cout<<"(1) Value对象Type:"<< PrintType(value1.type()) <<endl;
   cout<<"(2) Value对象Type:"<< PrintType(value2.type()) <<endl;
   cout<<"(3) Value对象Type:"<< PrintType(value3.type()) <<endl;
   cout<<"(4) Value对象Type:"<< PrintType(value4.type()) <<endl;
   cout<<"(5) Value对象Type:"<< PrintType(value5.type()) <<endl;
   cout<<"(6) Value对象Type:"<< PrintType(value6.type()) <<endl;
   cout<<"(7) Value对象Type:"<< PrintType(value7.type()) <<endl<<endl;  

#endif

/*! Jsoncpp测试 */
/* 2.2 Jsoncpp:value.h 尝试对各种Type的Value容器进行操作 */
/* 以及部分测试size()以及asString()成员函数 */
#if 0
   using namespace std;
   using namespace Json;

   string& PrintType(const ValueType& vaule_type);

   Value value;
   cout<<"使用默认构造函数构造value."<<endl;
   cout<<"value容器Type:"<< PrintType(value.type());
   cout<<boolalpha<<"value容器是否为空:"<< value.empty() <<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl<<endl;

   value = "Hello World!";
   cout<<"向value容器赋值 \"Hello Wrold!\" 后"<<endl;
   cout<<"value容器Type:"<< PrintType(value.type())<<endl;
   cout<<boolalpha<<"value容器是否为空:"<< value.empty() <<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl<<endl;

   cout<<"尝试向非objectValue类型的Value容器进行下标操作:"<<endl;
   //Error Code
   //value["color"] = "yellow";
   cout<<"库提供的编译信息:"<<endl;
   cout<<"terminate called after throwing an instance of 'Json::LogicError'"<<endl;
   cout<<"  what():  in Json::Value::resolveReference(key, end): requires objectValue"<<endl<<endl;

   cout<<"尝试向非array类型的value容器进行列表赋值操作："<<endl;
   //Error Code
   /*
   value[0] = 1;
   value[1] = true;
   value[3] = "Hello World!";
   */
   cout<<"库提供的编译信息:"<<endl;
   cout<<"terminate called after throwing an instance of 'Json::LogicError'"<<endl;
   cout<<"  what():  in Json::Value::operator[](ArrayIndex): requires arrayValue"<<endl<<endl;

   cout<<"将value对象转换为字符串,查看其输出结果:";
   cout<<value.asCString()<<endl<<endl;

   return 0;
#endif

/*! Jsoncpp测试 */
/* 2.3 Jsoncpp:value.h 测试Type类型为arrayValue类型的value容器操作 */
/* 以及部分测试size()以及asString()成员函数 */
#if 0
   using namespace std;
   using namespace Json;

   string& PrintType(const ValueType& vaule_type);

   Value value;
   cout<<"使用默认构造函数构造value."<<endl;
   cout<<"value容器Type:"<< PrintType(value.type());
   cout<<boolalpha<<"value容器是否为空:"<< value.empty() <<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl<<endl;

   value[0] = 1;
   cout<<"使用下标运算符对默认构造对象value进行赋值."<<endl;
   cout<<"value容器Type:"<< PrintType(value.type());
   cout<<boolalpha<<"value容器是否为空:"<< value.empty() <<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl<<endl;  

   value[3] = "Hello Wrold";
   cout<<"直接将下标索引从0移动至3，观察size以及中间填充的元素."<<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl<<endl;
   cout<<"使用迭代器对所有value进行遍历:"<<endl;
   for(Value::iterator json_iter = value.begin(); json_iter != value.end(); json_iter++)
     cout<<*json_iter<<" , ";
   cout<<endl; 
   cout<<"使用下标循环对value进行遍历:"<<endl;
   for(ArrayIndex i=0; i<4; i++)
     cout<<value[i]<<" , ";
   cout<<endl;
   cout<<"使用range-based进行遍历:"<<endl;
   for(Value& temp : value)
     cout<<temp<<" , ";
   cout<<endl<<endl;

   cout<<"测试isValidIndex成员函数."<<endl;
   cout<<"当前size为4，尝试输入idex为4，判断索引是否合法:";
   cout<<boolalpha<<value.isValidIndex(4)<<endl<<endl;

   cout<<"测试insert成员函数."<<endl;
   value.insert(1, true);
   value.insert(2, 'O');
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl;
   for(Value& temp : value)
     cout<<temp<<" , ";
   cout<<endl<<endl;

   cout<<"查看value容器下每个元素的类型:"<<endl;
   for(Value& temp : value)
     cout<<"Value:"<<temp<<" , "<<"Type:"<< PrintType(temp.type()) <<endl;
   cout<<endl;

   cout<<"将value对象转换为字符串:"<<endl;
   // Error code
   // cout<< value.asCString() <<endl<<endl;
   cout<< "Jsoncpp库提供的提示信息:" << endl;
   cout<< "terminate called after throwing an instance of 'Json::LogicError'"<<endl;
   cout<< "  what():  in Json::Value::asCString(): requires stringValue" <<endl;
   cout<<endl;

   cout<<"测试resize成员函数."<<endl;
   cout<<"使用resize将容器大小修改为3."<<endl;
   value.resize(3);
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl;
   for(Value& temp : value)
     cout<<temp<<" , ";
   cout<<endl<<endl;  
   
   const Value default_result = "NULL";
   cout<<"测试get成员函数."<<endl;
   cout<<"尝试读取value的第零个元素(若无返回NULL): "<< value.get(static_cast<ArrayIndex>(0), default_result) <<endl;
   cout<<"尝试读取value的第四个元素(若无返回NULL): "<< value.get(static_cast<ArrayIndex>(4), default_result) <<endl<<endl;

   return 0;
#endif

/*! Jsoncpp测试 */
/* 2.4 Jsoncpp:value.h 测试Type类型为obejectValue类型的value容器操作 */
/* 以及部分测试size()以及asString()成员函数 */
#if 0
   using namespace std;
   using namespace Json;

   string& PrintType(const ValueType& vaule_type);

   Value value;
   cout<<"使用默认构造函数构造value."<<endl;
   cout<<"value容器Type:"<< PrintType(value.type());
   cout<<boolalpha<<"value容器是否为空:"<< value.empty() <<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl<<endl;

   value["color"] = "yellow";
   cout<<"使用下标运算符对默认构造对象value进行赋值."<<endl;
   cout<<"value容器Type:"<< PrintType(value.type());
   cout<<boolalpha<<"value容器是否为空:"<< value.empty() <<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl;  
   cout<<"Key:"<<"color"<<" , "<<"Value:"<< value["color"] <<endl;
   cout<<endl;

   value["name"] = "2ha";
   value["animal"] = "dog";
   value["age"] = 4;
   cout<<"使用下标运算符继续对默认构造对象value进行赋值."<<endl;
   cout<<boolalpha<<"value容器的大小:"<< value.size() <<endl;  
   cout<<"Key:"<<"color"<<" , "<<"Value:"<< value["color"] <<endl;
   cout<<"Key:"<<"name"<<" , "<<"Value:"<< value["name"] <<endl;
   cout<<"Key:"<<"animal"<<" , "<<"Value:"<< value["animal"] <<endl;
   cout<<"Key:"<<"age"<<" , "<<"Value:"<< value["age"] <<endl;
   cout<<"Key:"<<"unknown"<<" , "<<"Value:"<< value["unknown"] <<endl;
   cout<<endl;
   
   return 0;
#endif

/*! Jsoncpp测试 */
/* 2.5 Jsoncpp:value.h 测试C/C++ style风格注释 */
#if 0
   using namespace std;
   using namespace Json;

   string& PrintType(const ValueType& vaule_type);

   Value value(objectValue);

   cout<<"创建一个objectValue的Value对象，检查是否存在注释:"<<endl;
   cout<<boolalpha<<"commentBefore:"<< value.hasComment(commentBefore) <<endl;
   cout<<boolalpha<<"commentAfterOnSameLine:"<< value.hasComment(commentAfterOnSameLine) <<endl;
   cout<<boolalpha<<"commentAfter:"<< value.hasComment(commentAfter) <<endl;
   cout<<boolalpha<<"numberOfCommentPlacement:"<< value.hasComment(numberOfCommentPlacement) <<endl;
   cout<<endl;
   
   cout<<"为value的每个部分添加注释:"<<endl;
   value.setComment(static_cast<const string>("/* 上行注释 */"), commentBefore);
   value.setComment(static_cast<const string>("/* 同行注释 */"), commentAfterOnSameLine);
   value.setComment(static_cast<const string>("/* 下行注释 */"), commentAfter);
   value.setComment(static_cast<const string>("//不知道哪行的注释 "), numberOfCommentPlacement);
   cout<<"再次检查每个部分是否存在注释:"<<endl;
   cout<<boolalpha<<"commentBefore:"<< value.hasComment(commentBefore) <<endl;
   cout<<boolalpha<<"commentAfterOnSameLine:"<< value.hasComment(commentAfterOnSameLine) <<endl;
   cout<<boolalpha<<"commentAfter:"<< value.hasComment(commentAfter) <<endl;
   cout<<boolalpha<<"numberOfCommentPlacement:"<< value.hasComment(numberOfCommentPlacement) <<endl;
   cout<<endl;
   
   cout<<"获取value每个部分注释"<<endl;
   cout<<"commentBefore:"<< value.getComment(commentBefore) <<endl;
   cout<<"commentAfterOnSameLine:"<< value.getComment(commentAfterOnSameLine) <<endl;
   cout<<"commentAfter:"<< value.getComment(commentAfter) <<endl;
   //cout<<"numberOfCommentPlacement:"<< value.getComment(numberOfCommentPlacement) <<endl;
   cout<<endl;

   return 0;
#endif

/*! Jsoncpp测试 */
/* 3.1 Jsoncpp:writerr.h StreamWriterBuilder  */
/* 对输出的配置进行检查以及修改 */
#if 0
   using namespace std;
   using namespace Json;

   string& PrintType(const ValueType& vaule_type);

   StreamWriterBuilder streamWriterBuilder;
   const Value& writers_settings =  streamWriterBuilder.settings_;
   cout<<"承载Writer Settings的Value容器类型:"<< PrintType(writers_settings.type()) <<endl;
   cout<<"streamWriterBuilder的大小:"<< writers_settings.size() <<endl;
   cout<<"streamWriterBuilder的配置:"<<endl;
   auto members = writers_settings.getMemberNames();
   for( const auto& name : members )
     cout<<"Key : "<< name <<" Value : "<< writers_settings[name]<<endl;
   cout<<boolalpha<<"检查配置是否正确:"<< streamWriterBuilder.validate(const_cast<Value*>(&writers_settings)) <<endl;
   cout<<endl;
   
   cout<<"对streamWriterBuilder的配置部分进行修改(正确示范):"<<endl;
   streamWriterBuilder["precision Value"] = 10;
   cout<<"streamWriterBuilder的配置:"<<endl;
   members = writers_settings.getMemberNames();
   for( const auto& name : members )
     cout<<"Key : "<< name <<" Value : "<< writers_settings[name]<<endl;
   cout<<boolalpha<<"检查配置是否正确:"<< streamWriterBuilder.validate(const_cast<Value*>(&writers_settings)) <<endl;
   cout<<endl;
   
   cout<<"对streamWriterBuilder的配置部分进行修改(错误示范):"<<endl;
   streamWriterBuilder["Color"] = "red";
   cout<<"streamWriterBuilder的配置:"<<endl;
   members = writers_settings.getMemberNames();
   for( const auto& name : members )
     cout<<"Key : "<< name <<" Value : "<< writers_settings[name]<<endl;
   cout<<boolalpha<<"检查配置是否正确:"<< streamWriterBuilder.validate(const_cast<Value*>(&writers_settings)) <<endl;
   cout<<endl;

   Value single_setting(objectValue);
   cout<<"检查当个配置是否正确:"<<"{\"commentStyle Value\":\"All\"}"<<endl;
   single_setting["commentStyle Value"] = "All";
   cout<<boolalpha<<"检查配置是否正确:"<< streamWriterBuilder.validate(&single_setting) <<endl;
   cout<<endl;  
   
   return 0;
#endif

/*! Jsoncpp测试 */
/* 3.2 Jsoncpp:reder.h StreamWriterBuilder  */
#if 0
   using namespace std;
   using namespace Json;

   
   // 创建一个供输出的Value测试对象
   Value root(objectValue);
   root["name"] = "2ha";
   root["animal"] = "dog";
   root["age"] = 3;
   root["hobbies"][0] = "run";
   root["hobbies"][1] = "drink";

   // 默认配置下输出json
   string& PrintType(const ValueType& vaule_type);
   StreamWriterBuilder builder;
   cout<<"带空格:"<<endl;
   unique_ptr<StreamWriter> writer(builder.newStreamWriter()); 
   writer->write(root, &cout);
   cout<<endl;
   
   // 修改配置输出json
   builder["dropNullPlaceholders Value"] = true;
   builder["indentation"] = " ";
   cout<<"除掉多余的空格:"<<endl;
   unique_ptr<StreamWriter> _writer{builder.newStreamWriter()}; 
   _writer->write(root, &cout);
   cout<<endl;  

   return 0;
#endif

/*! Jsoncpp测试 */
/* 4.1 Jsoncpp:reder.h CharReaderBuilder  */
/* 查看输入的默认配置 */
#if 0
   using namespace std;
   using namespace Json;

   CharReaderBuilder reader;
   Value& setting = reader.settings_;
   cout<<"CharReaderBuilder的默认配置"<<endl;
   vector<string> keys = setting.getMemberNames();
   for(auto& key : keys)
     cout<<"Key: "<<key<<" Value : "<<setting[key]<<endl;
   cout<<endl;
   
   cout<<"进行部分配置修改"<<endl;
   cout<<"修改完之后的配置为:"<<endl;
   reader["allowDroppedNullPlaceholders"] = true;
   reader["allowTrailingCommas"] = true;
   reader["failIfExtra"] = true;
   keys = setting.getMemberNames();
   for(auto& key : keys)
     cout<<"Key : "<<key<<" Value : "<<setting[key]<<endl;
   cout<<endl;   


   return 0;
#endif 

/*! Jsoncpp测试 */
/* 4.1 Jsoncpp:reder.h 解析Json(带注释)  */
/* 查看输入的默认配置 */
#if 0
   using namespace std;
   using namespace Json;

    /*! 从文件中读取json字符串 */
    ifstream ifile_json("../misc/config_doc");
    string  string_json;
    string_json.reserve(1024);
    //cout<<"sting缓冲区大小:"<< string_json.capacity() <<endl<<endl;
    if(ifile_json.good()){
#define  BUF_SIZE  256
      char* buf = new char[BUF_SIZE];
      while(1){
          ifile_json.clear();
          ifile_json.getline(buf, BUF_SIZE);
          string_json = string_json + static_cast<string>(buf);
          if(ifile_json.rdstate()  && ios_base::eofbit) break;
      }  
      delete[] buf;
      //cout<<"从文件中读取的json字符串为:"<<endl<<string_json<<endl;
#undef   BUF_SIZE 
    }else{
        cout<<"打开config_doc文件失败."<<endl;
        exit(-1);
    }
   //cout<<string_json<<endl;  

   CharReaderBuilder builder;
   builder["allowDroppedNullPlaceholders"] = true;
   builder["allowTrailingCommas"] = true;
   builder["failIfExtra"] = true;

   unique_ptr<CharReader> reader(builder.newCharReader());
   Value root;
   
   if(reader->parse(string_json.c_str() , string_json.c_str()+string_json.size(), &root, NULL))
   {
       cout<<"Json解析成功."<<endl;
       auto keys = root.getMemberNames();
       cout<<root<<endl;
   }else{
       cout<<"Json解析失败."<<endl;
   }

   cout<<"检查\"Encoding\"对象是否存在注释:"<<endl;
   bool has_comment = false;
   has_comment = root["encoding"].hasComment(commentBefore);
   if(has_comment){
       cout<<"上一行注释:"<< root["encoding"].getComment(commentBefore)<<endl;
   }
   has_comment = root["encoding"].hasComment(commentAfterOnSameLine);
   if(has_comment){
       cout<<"同行行注释:"<< root["encoding"].getComment(commentAfterOnSameLine)<<endl;
   }
   has_comment = root["encoding"].hasComment(commentAfter);
   if(has_comment){
       cout<<"下一行注释:"<< root["encoding"].getComment(commentAfter)<<endl;
   }


   return 0;
#endif 

/*! cURL测试 */
/* 1.1 获取简单的html(控制台输出) */
#if 0
  using namespace std;
  CURL *curl;
  CURLcode res;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");

    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return 0;
#endif

/*! cURL测试 */
/* 1.2 获取简单的html(存储到内存) */
#if 0
  using namespace std;
  CURL *curl_handle;
  CURLcode res;
  size_t 
  WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);

  struct MemoryStruct chunk;

  chunk.memory = (char *)malloc(1);  /* will be grown as needed by the realloc above */
  chunk.size = 0;    /* no data at this point */

  curl_global_init(CURL_GLOBAL_ALL);

  /* init the curl session */
  curl_handle = curl_easy_init();

  /* specify URL to get */
  curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.example.com/");

  /* send all data to this function  */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

  /* we pass our 'chunk' struct to the callback function */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);

  /* some servers do not like requests that are made without a user-agent
     field, so we provide one */
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  /* get it! */
  res = curl_easy_perform(curl_handle);

  /* check for errors */
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
  }
  else {
    /*
     * Now, our chunk.memory points to a memory block that is chunk.size
     * bytes big and contains the remote file.
     *
     * Do something nice with it!
     */

    printf("%lu bytes retrieved\n", (long)chunk.size);
    printf("%s\n", chunk.memory);
  }

  /* cleanup curl stuff */
  curl_easy_cleanup(curl_handle);

  free(chunk.memory);

  /* we are done with libcurl, so clean it up */
  curl_global_cleanup();

  return 0;
#endif

/*! cURL测试 */
/* 1.3 获取html(需要用户登陆) */
#if 0
  using namespace std;

  CURL *curl;
  CURLcode res;

  static const char *postthis = "user=daniel&password=monkey123";

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/login.cgi");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* redirects! */
    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* no file */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
    else {
      /*
       * After the login POST, we have received the new cookies. Switch
       * over to a GET and ask for the login-protected URL.
       */
      curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file");
      curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); /* no more POST */
      res = curl_easy_perform(curl);
      /* Check for errors */
      if(res != CURLE_OK)
        fprintf(stderr, "second curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));
    }
    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return 0;

#endif

/*! 百度云测试 */
/* 5.1 尝试用本地图片进行Base64编码后向服务器发送，测试是否可实现人脸检测  */
/* 对输出的配置进行检查以及修改 */
#if 0
   using namespace std;
   using namespace Json;
   using namespace BaiDuYun;
   const string ak = API_KEY; 
   const string sk = SECRET_KEY;

   // 建立 face句柄，并向服务器请求密钥
   Face face(ak, sk);
   string photoBuf;
#if 1
   ifstream jpegFile("../misc/xuezhiqian.jpeg", ios_base::in|ios_base::binary);
   if(jpegFile.is_open()){
     basic_istream<char>::pos_type photoSize = 0;

     /*！ 读取文件的大小,并为string分配合适的内存空间 */
     jpegFile.seekg(0, ios_base::end);
     photoSize = jpegFile.tellg();
     photoBuf.resize(static_cast<size_t>(photoSize)+1, 0);

     /*! 读取图像数据 */
     /* Hint:此操作十分危险，需要对底层有一定程度的了解 */
     jpegFile.seekg(0, ios_base::beg);
     jpegFile.read(const_cast<char *>(photoBuf.data()) , photoSize);

     /*! 关闭文件 */
     jpegFile.close();
   }else{
     cout<<"图片文件打开失败!"<<endl;
   }
#endif   

   face["image_type"] = "BASE64";
   face["liveness_control"]  = "LOW";
   if(face.FaceUpdate(photoBuf))
     cout<<"查询成功."<<endl;
   else
     cout<<"查询失败"<<endl;
#endif


/* 测试函数 */
using namespace std;
using namespace Json;

#if 1
/* 输出Value的类型 */
string& PrintType(const ValueType& vaule_type)
{
    static string result;
    result.clear();
    switch(vaule_type)
    {
        case nullValue: result += "nullValue";        break;
        case intValue: result += "intValue";          break;
        case uintValue: result += "uintValue";        break;
        case realValue: result += "realValue";        break;
        case stringValue: result += "stringValue";    break;
        case booleanValue: result += "booleanValue";  break;
        case arrayValue: result += "arrayValue";      break;
        case objectValue: result += "objectValue";    break;
        default : result += "erroerType";             break;
    }

    return result;
}
#endif

#if 0
/* cURL数据接受回调函数 */
size_t 
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
  if(mem->memory == NULL) {
    /* out of memory */
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}
#endif